﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameEngine.Scenes;

namespace GameEngine.animations
{
    public class SubjectAnimation
    {
        private HashSet<IOnAnimationFinishedListener> animFinishedListeners = new HashSet<IOnAnimationFinishedListener>();
        private HashSet<IOnAnimationFinishedListener> listenersMarkedForAdd = new HashSet<IOnAnimationFinishedListener>();
        private HashSet<IOnAnimationFinishedListener> listenersMarkedForRemove = new HashSet<IOnAnimationFinishedListener>();
        private bool onAnimFinished; //to know if it's iterating the animFinishedListeners list

        #region SingletonPattern
        private static SubjectAnimation instance;
        private SubjectAnimation() { }
        public static SubjectAnimation getInstance()
        {
            if(instance==null)
                instance = new SubjectAnimation();
            return instance;
        }
        #endregion

        #region Functionality
        public void addAnimFinishedListener(IOnAnimationFinishedListener listener) 
        {
            if (!onAnimFinished)
                animFinishedListeners.Add(listener); //if it's not iterating that list, the new listener can be added inmediately
            else
                listenersMarkedForAdd.Add(listener); //else must add it to a temporal list
        }
        public void markForRemoveAnimFinishedListener(IOnAnimationFinishedListener listener) 
        {
            listenersMarkedForRemove.Add(listener);
        }

        public void animFinished(DetailAnimation detAnim) 
        {
            removeMarkedAnimListener();
            onAnimFinished = true;
            foreach (IOnAnimationFinishedListener listener in animFinishedListeners) 
            {
                if(listener.getDetAnimWaitingToFinish().Contains(detAnim)) listener.onAnimationFinished(detAnim);
            }
            onAnimFinished = false;
            removeMarkedAnimListener();
            addMarkedAnimListener();
        }

        private void removeMarkedAnimListener() {
            if (listenersMarkedForRemove.Count > 0) //erase the listeners marked to be removed
            {
                foreach (IOnAnimationFinishedListener listenerToRemove in listenersMarkedForRemove)
                {
                    animFinishedListeners.Remove(listenerToRemove);
                }
                listenersMarkedForRemove.Clear();
            }
        }
        private void addMarkedAnimListener()
        {
            if (listenersMarkedForAdd.Count > 0) //erase the listeners marked to be removed
            {
                foreach (IOnAnimationFinishedListener listenerToAdd in listenersMarkedForAdd)
                {
                    animFinishedListeners.Add(listenerToAdd);
                }
                listenersMarkedForAdd.Clear();
            }
        }
        #endregion
    }
}
